// Test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdlib.h>
#include <windows.h>

char rndxx[64];
char hdid[20];

/* Data structure for MD5 (Message-Digest) computation */
typedef struct {
	ULONG i[2];                          /* number of _bits_ handled mod 2^64 */
	ULONG buf[4];                                           /* scratch buffer */
	unsigned char in[64];                                     /* input buffer */
	unsigned char digest[16];            /* actual digest after MD5Final call */
} MD5_CTX;

typedef void (WINAPI* PMD5Init) (MD5_CTX * ctx);
typedef void (WINAPI* PMD5Update)(MD5_CTX * ctx, const unsigned char * buf, unsigned int len);
typedef void (WINAPI* PMD5Final )(MD5_CTX * ctx);
typedef int (WINAPI __pfnsend)(IN SOCKET s, IN const char FAR * buf, IN int len, IN int flags);

PMD5Init MD5Init;
PMD5Update MD5Update;
PMD5Final MD5Final;

DWORD GetRand()
{
	return GetTickCount()*rand();;
}

void RandomHDID()
{
	int i;
	FILE * pFile = fopen ("M:\\Program Files (x86)\\xunyou\\HID.dat","r");
	if (pFile!=NULL)
	{
		fread(hdid,1,20,pFile);
		fclose(pFile);
	}else{
		for(i = 0; i < 20; i++)
		{
			hdid[i] = (BYTE)((WORD)GetRand() % 256);
		}
		pFile = fopen ("M:\\Program Files (x86)\\xunyou\\HID.dat","w");
		fwrite(hdid,1,20,pFile);
		fflush(pFile);
		fclose(pFile);
		::MessageBeep(1);
	}
	MD5_CTX ctx;
	char  md5tmp[64] = {0};

	MD5Init(&ctx);
	MD5Update(&ctx, (unsigned char *)hdid, 20);
	MD5Final(&ctx);

	for(i = 0; i < 16; i ++)
	{
		wsprintfA(&md5tmp[i * 2], "%02X", ctx.digest[i]);
	}
	strcpy(rndxx, md5tmp);

	strcat(rndxx, "zxcvbnm12");

	int len = strlen(rndxx);

	MD5Init(&ctx);
	MD5Update(&ctx, (BYTE*)rndxx, len);
	MD5Final(&ctx);

	for(i = 0; i < 16; i ++)
	{
		wsprintfA(&md5tmp[i * 2], "%02X", ctx.digest[i]);
	}

	memcpy(&rndxx[32], md5tmp, 32);
	return ;
}


int _tmain(int argc, _TCHAR* argv[])
{
	HINSTANCE hDLL;
		if ( (hDLL = LoadLibrary("Cryptdll.dll")) > 0 )
		{
			::OutputDebugString("Load Cryptdll");
			MD5Init = (PMD5Init)GetProcAddress(hDLL,"MD5Init");
			MD5Update = (PMD5Update)GetProcAddress(hDLL,"MD5Update");
			MD5Final = (PMD5Final)GetProcAddress(hDLL,"MD5Final");
		}

	RandomHDID();
	return 0;
}

